﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Linq.Expressions;
using System.Transactions;
using System.Web;

namespace TaDMS.Models
{
    public class DepartmentRepository : Repository<Department>
    {
        public DepartmentRepository(DbContext model) : base(model)
        {
        }

        public override IEnumerable<Department> GetData(out int? total, Func<IQueryable<Department>, IOrderedQueryable<Department>> orderBy, Expression<Func<Department, bool>> filter = null, IList<Expression<Func<Department, bool>>> multiFilter = null, string includeProperties = "", bool isPaging = false, int start = 0, int limit = 50)
        {
            try
            {
                IQueryable<Department> query = base.DbSet;
                IEnumerable<Department> result = null;

                if (filter != null)
                {
                    query = query.Where(filter);
                }
                if (multiFilter != null && multiFilter.Any())
                {
                    query = multiFilter.Aggregate(query, (current, expression) => current.Where(expression));
                }

                query = includeProperties.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Aggregate(query, (current, includeProperty) => current.Include(includeProperty));
                    
                if (isPaging)
                {
                    total = query.Count();

                    query = orderBy != null ? orderBy(query) : query;

                    query = query.Skip(start).Take(limit);

                    result = query.ToList().Select(t => new Department { DepartmentId = t.DepartmentId, Note = t.Note, DepartmentName = t.DepartmentName, DepartmentLevel = t.DepartmentLevel, ParentDepartmentId = t.ParentDepartmentId });

                    //total = result.Count();
                }
                else
                {
                    total = null;
                }

                return result;
               
            }
            catch (Exception exception)
            {
                this.ErrorMessage = exception.Message;

                total = null;

                return null;
            }
        }

        public List<Department> GetDepartmentTree()
        {
            using (var db = new TaDMS())
            {
                var parentDepartment = db.sp_Department_GetRoot().ToList();

                var result = parentDepartment.Select(rootResult => new Department() { DepartmentId = rootResult.DepartmentId, DepartmentName = rootResult.DepartmentName, Note = rootResult.Note, DepartmentLevel = rootResult.DepartmentLevel, ParentDepartmentId = rootResult.ParentDepartmentId }).ToList();

                GetList(result);

                return result;
            }
        }

        public override int? Delete(Department entity)
        {
            try
            {
                using (var db = new TaDMS())
                {
                    return db.sp_Department_Delete(entity.DepartmentId);
                }
            }
            catch (Exception exception)
            {
                ErrorMessage = exception.Message;

                return null;
            }
        }

        /*Private method*/
        private void GetList(IEnumerable<Department> source)
        {
            foreach (var department in source)
            {
                var newSource = new List<Department>();
                using (var db = new TaDMS())
                {
                    var data = db.sp_Department_GetChildren(department.DepartmentId).AsEnumerable();
                    newSource.AddRange(data.Select(result => new Department() { DepartmentId = result.DepartmentId, DepartmentName = result.DepartmentName, Note = result.Note, DepartmentLevel = result.DepartmentLevel, ParentDepartmentId = result.ParentDepartmentId }));
                }

                department.Department1 = newSource;

                this.GetList(newSource);
            }
        }
    }
}